#include "BlockQueue.hpp"
#include "Task.hpp"
#include <pthread.h>
#include <unistd.h>
#include <ctime>

int Add(int x, int y)
{
    return x + y;
}

void* consume(void* args)
{
    BlockQueue<Task>* bq = (BlockQueue<Task>*)args;
    while(1)
    {
        // 获取任务
        Task t;
        bq->pop(&t);
        // 完成任务
        std::cout << pthread_self() << " consumer: " << t._x << " + " << t._y << " = " << t() << std::endl;
    }
    return nullptr;
}

void* produce(void* args)
{
    BlockQueue<Task>* bq = (BlockQueue<Task>*)args;
    while(1)
    {
        // 制作任务 -- 不一定从生产者来的,可能是从网络来的
        int x = rand() % 10 + 1;
        int y = rand() % 20 + 1;
        // int x, y;
        // std::cout << "Please Enter x: ";
        // std::cin >> x;
        // std::cout << "Please Enter y: ";
        // std::cin >> y;
        // 生产任务
        Task t(x, y, Add);
        bq->push(t);
        std::cout << pthread_self() << " productor: " << x << " + " << y << " = ?" << std::endl; 
        sleep(1);
    }
    return nullptr;
}

int main()
{
    srand((unsigned int)time(nullptr) ^ getpid() ^ 0x123);
    BlockQueue<Task>* bq = new BlockQueue<Task>();
    // pthread_t c, p;

    pthread_t c[2], p[2];
    pthread_create(c, nullptr, consume, (void*)bq);
    pthread_create(c + 1, nullptr, consume, (void*)bq);
    pthread_create(p, nullptr, produce, (void*)bq);
    pthread_create(p + 1, nullptr, produce, (void*)bq);

    pthread_join(c[0], nullptr);
    pthread_join(c[1], nullptr);
    pthread_join(p[0], nullptr);
    pthread_join(p[1], nullptr);
    delete bq;

    return 0;
}